package com.doudou.feign;

import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.util.Assert;

/**
 * @Author: 傻男人
 * @Date: 2020/5/25 11:28
 * @Version: 1.0
 * @Description: 默认Hystrix失败工厂类
 */
@Slf4j
public class DefaultHystrixFallbackFactory implements FallbackFactory<Object> {

    private Class<?> feignClientClass;

    private HystrixFallbackHandlerFactory fallbackHandlerFactory;

    @Override
    public Object create(Throwable cause) {
        Assert.notNull(feignClientClass, "默认回调工厂的feign客户端未设置！");
        String name = feignClientClass.getName();
        if (cause instanceof RuntimeException && StringUtils.isEmpty(cause.getMessage())) {
            log.info("{} 的 hystrix 回调函数启用！", name);
        } else {
            log.info("feign client exception fall back  {}", cause.getMessage(), cause);
        }
        Assert.notNull(feignClientClass, "Property 'feignClientClass' must be required!");
        Assert.notNull(fallbackHandlerFactory, "Property 'fallbackHandlerFactory' must be required!");
        return doCreate(cause);
    }

    //这里要开启缓存
    protected Object doCreate(Throwable cause) {
        Enhancer enhancer = new Enhancer();
        enhancer.setClassLoader(Thread.currentThread().getContextClassLoader());
        enhancer.setSuperclass(getFeignClientClass());
        enhancer.setCallback(getFallbackHandlerFactory().createHandler(getFeignClientClass(), cause));
        return enhancer.create();
    }

    public HystrixFallbackHandlerFactory getFallbackHandlerFactory() {
        return fallbackHandlerFactory;
    }

    public void setFallbackHandlerFactory(HystrixFallbackHandlerFactory fallbackHandlerFactory) {
        this.fallbackHandlerFactory = fallbackHandlerFactory;
    }

    public Class<?> getFeignClientClass() {
        return feignClientClass;
    }

    public void setFeignClientClass(Class<?> feignClientClass) {
        this.feignClientClass = feignClientClass;
    }

}
